package gnolls.dao.impl;

import gnolls.dao.GenericDao;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

/**
 * Implementation of the GenericDao interface. Base class for another DAO classes.
 */
public abstract class GenericDaoImpl<T, PK extends Serializable> implements GenericDao<T, PK> {

	// Fields ======================================================================================

	/** Session factory instrumented by the Spring engine. */
	private SessionFactory sessionFactory = null;

	// Methods =====================================================================================

	/** {@inheritDoc} */
	@SuppressWarnings("unchecked")
	public final PK create(T o) {
		return (PK) getSession().save(o);
	}

	/** {@inheritDoc} */
	@SuppressWarnings("unchecked")
	public final T find(PK id) {
		return (T) getSession().get(getType(), id);
	}

	/** {@inheritDoc} */
	@SuppressWarnings("unchecked")
	public final List<T> findAll() {
		Query query = getSession().createQuery("From " + getType().getName());
		return query.list();
	}

	/** {@inheritDoc} */
	public final void update(T o) {
		getSession().saveOrUpdate(o);
	}

	/** {@inheritDoc} */
	public final void delete(T o) {
		getSession().delete(o);
	}

	/** Returns active DB session. */
	protected final Session getSession() {
		return sessionFactory.getCurrentSession();
	}

	/** Returns class of the domain object. */
	protected abstract Class<T> getType();

	// Getters & Setters ===========================================================================

	public final SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public final void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

}
